﻿using System.Windows;
using System.Windows.Controls;

namespace LS.Screening.UI.Common
{
    public static class ViewModelExtensions
    {
        /// <summary>
        /// 显示弹窗
        /// </summary>
        /// <param name="vm"></param>
        /// <param name="viewAssembly"></param>
        /// <param name="viewFullName"></param>
        /// <param name="title"></param>
        /// <param name="action"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="resizeMode"></param>
        /// <returns></returns>
        public static async Task<ContentControl> ShowDialog(this IViewModel vm, string viewAssembly, string viewFullName, string title, Action<IViewModel, Window> action = null, int width = 0, int height = 0, ResizeMode resizeMode = ResizeMode.CanResize)
        {
            return await Application.Current.MainWindow.Dispatcher.InvokeAsync(() =>
            {
                var fullName = vm.GetType().FullName.Replace(".ViewModels.", ".Views.").Replace("ViewModel", "View");
                var assemblyName = fullName.Substring(0, fullName.IndexOf(".Views"));
                if (!System.IO.File.Exists(assemblyName + ".dll"))
                {
                    assemblyName = fullName.Substring(0, fullName.IndexOf(".Views") + 6);
                }

                var view = TypeHelper.CreateInstance<ContentControl>(viewAssembly, viewFullName);
                Window window = new Window();
                window.Content = view;
                window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                window.Style = (Style)Application.Current.Resources["WindowWin10"];
                window.Owner = Application.Current.MainWindow;
                if (width <= 0 || height <= 0)
                {
                    window.SizeToContent = SizeToContent.Manual;
                    window.ResizeMode = resizeMode;
                    if (view.Width > 0)
                    {
                        window.Width = view.Width;
                        window.Height = view.Height;
                        if (window.Width < 300)
                        {
                            window.Width = 300;
                        }
                    }
                }
                else
                {
                    window.Width = width;
                    window.Height = height;
                }
                window.Title = title;
                window.ResizeMode = resizeMode;
                if (window.Height > SystemParameters.WorkArea.Height || window.Width > SystemParameters.WorkArea.Width)
                {
                    window.WindowState = WindowState.Maximized;
                }

                window.Loaded += (a, b) =>
                {
                    vm = (IViewModel)view.DataContext;
                    action?.Invoke(vm, window);
                    vm.Init();
                };
                window.ShowDialog();
                return view;
            });
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <typeparam name="VM"></typeparam>
        /// <param name="v"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView<VM>(this IViewModel v, Action<VM> action = null) where VM : ViewModel, new()
        {
            return GetView<VM>(action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <param name="v"></param>
        /// <param name="viewModelType"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView(this IViewModel v, Type viewModelType, Action<IViewModel> action = null)
        {
            return GetView(viewModelType, action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <typeparam name="VM"></typeparam>
        /// <param name="v"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView<VM>(this UserControl v, Action<VM> action = null) where VM : ViewModel, new()
        {
            return GetView<VM>(action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <param name="v"></param>
        /// <param name="viewModelType"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView(this UserControl v, Type viewModelType, Action<IViewModel> action = null)
        {
            return GetView(viewModelType, action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <typeparam name="VM"></typeparam>
        /// <param name="v"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView<VM>(this Window v, Action<VM> action = null) where VM : ViewModel, new()
        {
            return GetView<VM>(action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <param name="v"></param>
        /// <param name="viewModelType"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView(this Window v, Type viewModelType, Action<IViewModel> action = null)
        {
            return GetView(viewModelType, action);
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <typeparam name="VM"></typeparam>
        /// <param name="action">视图模型操作方法</param>
        /// <returns></returns>
        public static Control GetView<VM>(Action<VM> action = null) where VM : ViewModel, new()
        {
            var viewFullName = typeof(VM).FullName.Replace(".ViewModels.", ".Views.").Replace("ViewModel", "View");
            var viewAssemblyName = typeof(VM).Assembly.GetName().Name.Replace(".ViewModels.", ".Views.").Replace("ViewModel", "View");
            var control = TypeHelper.CreateInstance<Control>(viewAssemblyName, viewFullName);
            if (action != null)
            {
                var viewModel = control.DataContext as VM;
                if (viewModel != null)
                {
                    action?.Invoke(viewModel);
                }
            }
            return control;
        }

        /// <summary>
        /// 通过ViewModel获取View
        /// </summary>
        /// <param name="viewModelType"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static Control GetView(Type viewModelType, Action<IViewModel> action = null)
        {
            var viewFullName = viewModelType.FullName.Replace(".ViewModels.", ".Views.").Replace("ViewModel", "View");
            var viewAssemblyName = viewModelType.Assembly.GetName().Name.Replace(".ViewModels.", ".Views.").Replace("ViewModel", "View");
            var control = TypeHelper.CreateInstance<Control>(viewAssemblyName, viewFullName);
            if (action != null)
            {
                var viewModel = (IViewModel)control.DataContext;
                if (viewModel != null)
                {
                    action?.Invoke(viewModel);
                }
            }
            return control;
        }
    }
}
